from django.http import HttpResponseBadRequest,JsonResponse
from django.shortcuts import render,HttpResponse,redirect
from django.urls import reverse
from django.views import View
from libs.yuntongxun.sms import CCP
from users.models import User
from django.contrib.auth import login
from django.contrib.auth import authenticate
from django.contrib.auth import logout
# Create your views here.
from django.db import DataError
import json
from home.models import ArticleCategory, Article

from django.contrib.auth.mixins import LoginRequiredMixin# 注册视图
from django_redis import get_redis_connection
from libs.captcha.captcha import captcha
from utils.response_code import RETCODE
import logging  # 导入loggin包
from random import randint  # 导入随机数包
import re

class RegisterView(View):
    # 注册页面展示
    def get(self,request):
        return render(request,'register.html')

    def post(self, request):
        '''
        实现思路：
        1、接收用户数据
        2、验证数据
            2-1、参数是否齐全
            2-2、手机号格式是否正确
            2-3、密码是否符合格式
            2-4、密码和确认密码是否一致
            2-5、短信验证码是否和redis中的一致
        3、保存注册信息
        4、返回响应跳转到指定页面
        :param request:
        :return:
        '''
        # 1、接收用户数据
        mobile = request.POST.get('mobile')
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        sms_code = request.POST.get('sms_code')
        # 2、验证数据
        # 2-1、参数是否齐全
        if not all([mobile, password, password2, sms_code]):
            return HttpResponseBadRequest('缺少必要参数')
        # 2-2、手机号格式是否正确
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return HttpResponseBadRequest('手机号码格式不正确')
        # 2-3、密码是否符合格式
        if not re.match(r'^[0-9a-zA-Z]{8,20}$', password) or not re.match(r'^[0-9a-zA-Z]{8,20}$', password2):
            return HttpResponseBadRequest('密码长度、格式不正确。长度8-20，必须是数字、字母')
        # 2-4、密码和确认密码是否一致
        if password != password2:
            return HttpResponseBadRequest('两次输入的密码不一致')
        # 2 - 5、短信验证码是否和redis中的一致
        redis_conn = get_redis_connection()
        sms_code_redis = redis_conn.get('img:%s' % mobile)
        if sms_code_redis is None:
            return HttpResponseBadRequest('短信验证码过期')
        try:# 删除验证码，避免恶意测试验证码
            redis_conn.delete('sms:%s' % mobile)
        except Exception as e:
            logger.error(e)
        if sms_code_redis.decode() != sms_code:
            return HttpResponseBadRequest('验证码错误')
        try:
            user=User.objects.create_user(username=mobile, mobile=mobile, password=password)
            login(request,user)
        except DataError as e:
            logger.error(e)
            return HttpResponseBadRequest('注册失败')
        resp=redirect(reverse('home:index'))
        resp.set_cookie('is_login', True)
        resp.set_cookie('login_name',user.username)
        return resp


class ImageView(View):
    def get(self,request):
        uuid = request.GET.get('uuid')
        if uuid is None:
            return HttpResponseBadRequest('uuid不存在')
        txt, image = captcha.generate_captcha()
        redis_conn = get_redis_connection('default')
        redis_conn.setex(name='img:%s' % uuid, time=300, value=txt)
        return HttpResponse(image,content_type='image/jpeg')


class SmsCodeView(View):
    def get(self,request):
       mobile=request.GET.get('mobile')
       image_code = request.GET.get('image_code')
       uuid = request.GET.get('uuid')
       # 参数校验
       if not all([mobile,image_code,uuid]):
           return HttpResponseBadRequest(content='参数不齐全')
       redis_conn=get_redis_connection()
       image_code_redis=redis_conn.get('img:%s' % uuid)
       if image_code_redis is None:
           return HttpResponseBadRequest(content='图片验证码不存在')
       redis_conn.delete('img:%s' % uuid)
       if image_code!=image_code_redis.decode().lower():
           return HttpResponseBadRequest(content='图片验证错误')
       sms_code = '%06d' % randint(0, 999999)
       cpp = CCP()
       cpp.send_template_sms('17806802847',['sms_code',1],1)
       print(f'你的验证码是：{sms_code}')
       redis_conn.setex('img:%s' % mobile, 60, sms_code)
       return JsonResponse({"code": RETCODE.OK,"errmsg":'短信验证码'})

class LoginView(View):
    def get(self,request):
        return render(request,'login.html')

    def post(self, request):
        mobile = request.POST.get('mobile')
        password = request.POST.get('password')
        remember = request.POST.get('remember')

        if not all([mobile, password]):
            return HttpResponseBadRequest('缺少必要参数')
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return HttpResponseBadRequest('手机号码格式不正确')
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return HttpResponseBadRequest('密码格式不正确')
        return_user = authenticate(mobile=mobile, password=password)
        if return_user is None:
            return HttpResponseBadRequest('用户名或密码错误')
        login(request, return_user)
        next_page = request.GET.get('next')
        if next_page:
            resp = redirect(next_page)
        else:
            resp = redirect(reverse('home:index'))
        if remember != 'on':  # 没有记住用户信息
            request.session.set_expiry(0)
            resp.set_cookie('is_login', True)
            resp.set_cookie('login_name',)
        else:
            request.session.set_expiry(None)
            resp.set_cookie('is_login', True, max_age=14*24*3600)
            resp.set_cookie('login_name', return_user.username, 14*24*3600)
        return resp


class LogoutView(View):
    def get(self, request):
        '''
        实现思路：
        1、清楚session数据
        2、删除cookie数据
        3、跳转到首页
        :param request:
        :return:
        '''
        # 实现思路：
        # 1、清楚session数据
        logout(request)
        # 2、删除cookie数据
        resp = redirect(reverse('home:index'))
        resp.delete_cookie('is_login')
        resp.delete_cookie('login_name')
        # 3、跳转到首页
        return resp


class ForgetPasswordView(View):
    def get(self, request):
        return render(request, 'forget_password.html')

    def post(self, request):
        mobile = request.POST.get('mobile')
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        sms_code = request.POST.get('sms_code')
        # 2、验证数据
        # 2-1、判断参数是否齐全
        if not all([mobile, password, password2, sms_code]):
            return HttpResponseBadRequest('缺少必要的参数')
        # 2-2、手机号是否符合规则
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return HttpResponseBadRequest('手机格式不正确')
        # 2-3、判断密码是否符合规则
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return HttpResponseBadRequest('密码格式不正确')
        # 2-4、判断确认密码是否一致
        if password != password2:
            return HttpResponseBadRequest('两次密码输入不一致')
        # 2-5、判断短信验证码是否正确
        redis_conn = get_redis_connection('default')
        redis_sms_code = redis_conn.get('sms:%s' % mobile)
        # if redis_sms_code is None:
        #     return HttpResponseBadRequest('短信验证码过期')
        # try:
        #     if redis_sms_code.decode() != sms_code:
        #         return HttpResponseBadRequest('验证码错误')
        # except Exception as e:
        #     logger.error(e)
        #     return HttpResponseBadRequest('验证码错误')
        # # 3、根据手机号码进行用户信息的查询
        return_user = User.objects.filter(mobile=mobile).first()
        # 4、如果手机号查询出用户信息则进行用户密码的修改
        # 5、如果手机号没有查询出用户信息，则进行新用户的创建
        if return_user is None:
            try:
                User.objects.create_user(username=mobile, mobile=mobile, password=password)
            except Exception as e:
                logger.error(e)
                return HttpResponseBadRequest('注册失败')
        else:
            try:
                # 调用系统user对象的set_password()进行修改密码，该方法会对密码进行加密
                return_user.set_password(password)
                return_user.save()
            except Exception as e:
                logger.error(e)
                return HttpResponseBadRequest('修改密码失败')
        # 6、进行页面跳转，跳转到登录页面
        resp = redirect(reverse('users:login'))
        # 7、返回响应
        return resp


class UserCenterView(LoginRequiredMixin,View):
    def get(self, request):
        # 获取已经登录用户的信息
        userinfo = request.user
        context = {
            'username': userinfo.username,
            'mobile': userinfo.mobile,
            'avatar': userinfo.avatar.url if userinfo.avatar else None,
            'user_desc': userinfo.user_desc
        }
        return render(request, 'usercenter.html', context=context)

    def post(self, request):
        '''
        实现思路：
        1、接收用户参数
        2、将用户参数更新到数据库
        3、更新cookie中的username
        4、刷新当前页面（重定向操作）
        5、返回相应
        :param request:
        :return:
        '''
        # 获取已经登录用户的信息
        userinfo = request.user
        # 1、接收用户参数
        # 获取用户提交的用户名，如果没有就将已登录的用户名赋值
        username = request.POST.get('username', userinfo.username)
        # 获取用户提交的介绍，如果没有就将已登录的介绍赋值
        user_desc = request.POST.get('desc', userinfo.user_desc)
        # 获取用户头像(如果没有图片保存地址，则会默认保存到项目的根目录下。否则需要在settting中进行配置地址)
        avatar = request.FILES.get('avatar')
        # 2、将用户参数更新到数据库
        try:
            userinfo.username = username
            userinfo.user_desc = user_desc
            if avatar:
                userinfo.avatar = avatar
            userinfo.save()
        except Exception as e:
            logger.error(e)
            return HttpResponseBadRequest('修改用户信息失败')
        # 3、更新cookie中的username
        # 4、刷新当前页面（重定向操作）
        resp = redirect(reverse('home:index'))
        resp.set_cookie('login_name', userinfo.username)
        # 5、返回相应
        return resp

from home.models import *


class WriteBlogView(View):
    def get(self, requset):
        contxt=ArticleCategory.objects.all()
        return render(requset, 'writeblog.html',context={"list": contxt })

    def post(self, request):
        avatar = request.FILES.get('avatar')
        title = request.POST.get('title')
        category_id = request.POST.get('category')
        tags = request.POST.get('tags')
        sumary = request.POST.get('sumary')
        content = request.POST.get('content')
        user = request.user
        print([avatar, title, category_id, sumary, content])
        if not all([avatar, title, category_id, sumary, content]):
            return HttpResponseBadRequest('参数不齐全')
        try:
            category = ArticleCategory.objects.filter(pk=category_id).first()
        except ArticleCategory.DoesNotExist:
            return HttpResponseBadRequest('没有该分类信息')
        try: Article.objects.create(
             author=user,
             avatar=avatar,
             category=category,
             tags=tags,
             sumary=sumary,
             content=content
        )
        except Exception as e:
            logger.error(e)
            return HttpResponseBadRequest('发布失败，请稍后重试')
        return redirect(reverse('home:index'))

